/*
 * 本程序基于Eclipse编写
 * 测试依赖包 JUnit 4
 */

package calculateArea;

import org.junit.Before;
import org.junit.Test;
import org.junit.After;
import static org.junit.Assert.*;
import java.lang.reflect.Field;

public class CalculateAreaTest {
    
    private static final double DELTA = 0.001;
    
    @Before
    public void setUp() {
        // 测试前的初始化工作
    }
    
    @After
    public void tearDown() {
        // 测试后的清理工作
    }
   
    
    // 测试长方形面积计算 - 正常情况
    @Test
    public void testRectangleAreaNormal() {
        CalculateArea.Rectangle rectangle = new CalculateArea.Rectangle();
        rectangle.setLength(5.0);
        rectangle.setWidth(3.0);
        
        double expectedArea = 15.0;
        double actualArea = rectangle.calculateArea();
        
        assertEquals("长方形面积计算错误", expectedArea, actualArea, DELTA);
    }
    
    
    // 测试长方形周长计算 - 正常情况
    @Test
    public void testRectanglePerimeterNormal() {
        CalculateArea.Rectangle rectangle = new CalculateArea.Rectangle();
        rectangle.setLength(5.0);
        rectangle.setWidth(3.0);
        
        double expectedPerimeter = 16.0;
        double actualPerimeter = rectangle.calculatePerimeter();
        
        assertEquals("长方形周长计算错误", expectedPerimeter, actualPerimeter, DELTA);
    }
    
    // 测试长方形面积计算 - 小数情况
    @Test
    public void testRectangleAreaDecimal() {
        CalculateArea.Rectangle rectangle = new CalculateArea.Rectangle();
        rectangle.setLength(5.5);
        rectangle.setWidth(2.2);
        
        double expectedArea = 12.10;
        double actualArea = rectangle.calculateArea();
        
        assertEquals("长方形小数面积计算错误", expectedArea, actualArea, DELTA);
    }
  
    
    // 测试正方形面积计算
    @Test
    public void testSquareArea() {
        CalculateArea.Square square = new CalculateArea.Square();
        square.setLength(4.0);
        
        double expectedArea = 16.0;
        double actualArea = square.calculateArea();
        
        assertEquals("正方形面积计算错误", expectedArea, actualArea, DELTA);
    }
    
    
    // 测试正方形周长计算
    @Test
    public void testSquarePerimeter() {
        CalculateArea.Square square = new CalculateArea.Square();
        square.setLength(4.0);
        
        double expectedPerimeter = 16.0;
        double actualPerimeter = square.calculatePerimeter();
        
        assertEquals("正方形周长计算错误", expectedPerimeter, actualPerimeter, DELTA);
    }
    
    
    // 测试等腰三角形面积计算
    @Test
    public void testIsoscelesTriangleArea() {
        CalculateArea.IsoscelesTriangle triangle = new CalculateArea.IsoscelesTriangle();
        triangle.setBase(6.0);
        triangle.setHeight(4.0);
        
        double expectedArea = 12.0;
        double actualArea = triangle.calculateArea();
        
        assertEquals("等腰三角形面积计算错误", expectedArea, actualArea, DELTA);
    }
    
    // 测试等腰三角形周长计算
    @Test
    public void testIsoscelesTrianglePerimeter() {
        CalculateArea.IsoscelesTriangle triangle = new CalculateArea.IsoscelesTriangle();
        triangle.setBase(6.0);
        triangle.setHeight(4.0);
        
        // 腰长 = sqrt((6/2)^2 + 4^2) = sqrt(9 + 16) = sqrt(25) = 5
        // 周长 = 6 + 5*2 = 16
        double expectedPerimeter = 16.0;
        double actualPerimeter = triangle.calculatePerimeter();
        
        assertEquals("等腰三角形周长计算错误", expectedPerimeter, actualPerimeter, DELTA);
    }
    
    
    // 测试等腰梯形面积计算
    @Test
    public void testIsoscelesTrapezoidArea() {
        CalculateArea.IsoscelesTrapezoid trapezoid = new CalculateArea.IsoscelesTrapezoid();
        trapezoid.setUpperLine(3.0);
        trapezoid.setLowerLine(7.0);
        trapezoid.setHeight(4.0);
        
        double expectedArea = 20.0; // (3+7)*4/2 = 20
        double actualArea = trapezoid.calculateArea();
        
        assertEquals("等腰梯形面积计算错误", expectedArea, actualArea, DELTA);
    }
    

    // 测试等腰梯形周长计算
    @Test
    public void testIsoscelesTrapezoidPerimeter() {
        CalculateArea.IsoscelesTrapezoid trapezoid = new CalculateArea.IsoscelesTrapezoid();
        trapezoid.setUpperLine(3.0);
        trapezoid.setLowerLine(7.0);
        trapezoid.setHeight(4.0);
        
        // 腰长 = sqrt(((7-3)/2)^2 + 4^2) = sqrt(4 + 16) = sqrt(20) ≈ 4.472
        // 周长 = 3 + 7 + 2*4.472 ≈ 18.944
        double expectedPerimeter = 18.94; // 四舍五入后
        double actualPerimeter = trapezoid.calculatePerimeter();
        
        assertEquals("等腰梯形周长计算错误", expectedPerimeter, actualPerimeter, 0.01);
    }
    
    
    // 测试平行四边形面积计算
    @Test
    public void testParallelogramArea() {
        CalculateArea.Parallelogram parallelogram = new CalculateArea.Parallelogram();
        parallelogram.setBase(5.0);
        parallelogram.setHeight(3.0);
        
        double expectedArea = 15.0;
        double actualArea = parallelogram.calculateArea();
        
        assertEquals("平行四边形面积计算错误", expectedArea, actualArea, DELTA);
    }
    

    // 测试平行四边形周长计算
    @Test
    public void testParallelogramPerimeter() {
        CalculateArea.Parallelogram parallelogram = new CalculateArea.Parallelogram();
        parallelogram.setBase(5.0);
        parallelogram.setSide(3.0);
        
        double expectedPerimeter = 16.0; // 2*(5+3) = 16
        double actualPerimeter = parallelogram.calculatePerimeter();
        
        assertEquals("平行四边形周长计算错误", expectedPerimeter, actualPerimeter, DELTA);
    }
    

    // 测试圆形面积计算
    @Test
    public void testCircleArea() {
        CalculateArea.Circle circle = new CalculateArea.Circle();
        circle.setRadius(2.0);
        
        double expectedArea = 12.57; // π*2^2 ≈ 12.566 -> 12.57
        double actualArea = circle.calculateArea();
        
        assertEquals("圆形面积计算错误", expectedArea, actualArea, DELTA);
    }
    
    
    // 测试圆形周长计算
    @Test
    public void testCirclePerimeter() {
        CalculateArea.Circle circle = new CalculateArea.Circle();
        circle.setRadius(2.0);
        
        double expectedPerimeter = 12.57; // 2*π*2 ≈ 12.566 -> 12.57
        double actualPerimeter = circle.calculatePerimeter();
        
        assertEquals("圆形周长计算错误", expectedPerimeter, actualPerimeter, DELTA);
    }
    

    // 测试零值情况 - 长方形
    @Test
    public void testRectangleZeroValues() {
        CalculateArea.Rectangle rectangle = new CalculateArea.Rectangle();
        rectangle.setLength(0.0);
        rectangle.setWidth(5.0);
        
        double expectedArea = 0.0;
        double actualArea = rectangle.calculateArea();
        
        assertEquals("零值长方形面积计算错误", expectedArea, actualArea, DELTA);
    }
    

    // 测试小数精度 - 圆形
    @Test
    public void testCirclePrecision() {
        CalculateArea.Circle circle = new CalculateArea.Circle();
        circle.setRadius(1.5);
        
        double expectedArea = 7.07; // π*1.5^2 ≈ 7.068 -> 7.07
        double actualArea = circle.calculateArea();
        
        assertEquals("圆形精度计算错误", expectedArea, actualArea, DELTA);
    }
    

    // 测试大数值计算
    @Test
    public void testLargeValues() {
        CalculateArea.Rectangle rectangle = new CalculateArea.Rectangle();
        rectangle.setLength(1000.0);
        rectangle.setWidth(1000.0);
        
        double expectedArea = 1000000.0;
        double actualArea = rectangle.calculateArea();
        
        assertEquals("大数值计算错误", expectedArea, actualArea, DELTA);
    }
    
    // 测试Getter方法
    @Test
    public void testGetterMethods() {
        CalculateArea.Rectangle rectangle = new CalculateArea.Rectangle();
        rectangle.setLength(5.0);
        rectangle.setWidth(3.0);
        
        // 先计算面积和周长
        rectangle.calculateArea();
        rectangle.calculatePerimeter();
        
        // 测试getter方法
        assertEquals("面积getter错误", 15.0, rectangle.getArea(), DELTA);
        assertEquals("周长getter错误", 16.0, rectangle.getPerimeter(), DELTA);
    }
    
    
    // 测试所有图形类实例化
    @Test
    public void testAllShapesInstantiation() {
        // 测试所有图形类都能正常实例化
        assertNotNull("长方形实例化失败", new CalculateArea.Rectangle());
        assertNotNull("正方形实例化失败", new CalculateArea.Square());
        assertNotNull("等腰三角形实例化失败", new CalculateArea.IsoscelesTriangle());
        assertNotNull("等腰梯形实例化失败", new CalculateArea.IsoscelesTrapezoid());
        assertNotNull("平行四边形实例化失败", new CalculateArea.Parallelogram());
        assertNotNull("圆形实例化失败", new CalculateArea.Circle());
    }
    
    
    // 测试MyShape抽象类功能
    @Test
    public void testMyShapeAbstractClass() {
        // 测试抽象类的设计是否正确
        CalculateArea.Rectangle rectangle = new CalculateArea.Rectangle();
        
        assertTrue("MyShape实例检查失败", rectangle instanceof CalculateArea.MyShape);
        
        // 测试抽象方法存在
        try {
            rectangle.calculateArea();
            rectangle.calculatePerimeter();
            // 如果没有抛出异常，测试通过
            assertTrue("抽象方法测试通过", true);
        } catch (Exception e) {
            fail("抽象方法执行失败: " + e.getMessage());
        }
    }
}